package com.sloan.community.filter;

import com.sloan.community.config.AuthUrlProperties;
import com.sloan.community.po.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.PriorityOrdered;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Objects;

import static com.sloan.community.common.Constant.SESSION_USER;

//@Component 不再使用,比较麻烦
@Deprecated
public class PathLoginWebFilter implements WebFilter, PriorityOrdered {

    @Autowired
    private AuthUrlProperties authUrlProperties;

    private static final AntPathMatcher matcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        String path = exchange.getRequest().getURI().getPath();
        if (this.shouldAuthPath(path)) {
            return exchange.getSession()
                    .flatMap(webSession -> {
                        User user = webSession.getAttribute(SESSION_USER);
                        if (Objects.nonNull(user)) {
                            return chain.filter(exchange);
                        }
                        //return this.redirectLoginPage(exchange);
                        return this.forwardLoginPage(exchange, chain);
                    });
        }

        return chain.filter(exchange);
    }

    public boolean shouldAuthPath(String path) {
        for (String skipUrl : authUrlProperties.getUrl()) {
            if (matcher.match(skipUrl, path)) {
                return true;
            }
        }
        return false;
    }

    public Mono<Void> forwardLoginPage(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest()
                .mutate()
                .method(HttpMethod.GET)
                .path("/login.html") // TODO 等待优化，看能不能放到请求域中
                .header("msg","用户信息失效，请重新登录！")
                .build();

        ServerWebExchange newExchange = exchange.mutate().request(request).build();
        return chain.filter(newExchange);
    }

    public Mono<Void> redirectLoginPage(ServerWebExchange exchange) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.FOUND);
        response.getHeaders().setLocation(URI.create("/login.html"));
        return response.setComplete();
//        Mono<String> bodyMono = Mono.just("用户信息失效,请重新登录！");
//        return response.writeWith(bodyMono.map(msg->{
//            byte[] bytes = msg.getBytes(StandardCharsets.UTF_8);
//            response.getHeaders().setContentLength(bytes.length);
//            return response.bufferFactory().wrap(bytes);
//        }));
    }

    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE;
    }
}
